// Hispaniola -- JSB
// March 2006
// Main entry point for random map script    

include "mercenaries.xs";
include "triggers\triggerLoader.xs";
include "ypAsianInclude.xs";
include "ypKOTHInclude.xs";

void main(void)
{
	// --------------- Make load bar move. ----------------------------------------------------------------------------
	rmSetStatusText("",0.10);

	// Define Carib Natives
	int subCiv0=-1;
	int subCiv1=-1;
	int subCiv2=-1;

    if (rmAllocateSubCivs(3) == true)
    {
		subCiv0=rmGetCivID("caribs");
		rmEchoInfo("subCiv0 is caribs "+subCiv0);
		if (subCiv0 >= 0)
		rmSetSubCiv(0, "caribs");

		subCiv1=rmGetCivID("caribs");
		rmEchoInfo("subCiv1 is caribs "+subCiv1);
		if (subCiv1 >= 0)
		rmSetSubCiv(1, "caribs");

		subCiv2=rmGetCivID("caribs");
		rmEchoInfo("subCiv2 is caribs "+subCiv2);
		if (subCiv2 >= 0)
		rmSetSubCiv(2, "caribs");
	}

	// --------------- Make load bar move. ----------------------------------------------------------------------------
	rmSetStatusText("",0.20);
	
	// Map variations: 
	// 1 - Four Caribs, next to the big mountain and at the ends of the 2 long peninsulas. 
	// 2 - Four Caribs, at the ends of the 2 long peninsulas, and 2 on SE end of island.
    // 3 - Six Caribs, next to the mountain, 2 on the long peninsula, and 2 on SE end of island. 

	int whichVariation=-1;
	whichVariation = rmRandInt(1,3);
	// The line below can be uncommented to force the variation to the number indicated, for testing.
	// whichVariation = 3; 

	rmEchoInfo("Map Variation: "+whichVariation);
	
	chooseMercs();
	wotta_triggers();

	if ( cNumberNonGaiaPlayers > 7 )	//If 8 player game, use only variation #2 so map builds more quickly.
	{
		whichVariation = 2;
	}
	
	// Set size of map
	int playerTiles=23500;
	if (cNumberNonGaiaPlayers >4)   // If more than 4 players...
		playerTiles = 18000;		// ...give this many tiles per player.
	if (cNumberNonGaiaPlayers >7)	// If more than 7 players...
		playerTiles = 20000;		// ...give this many tiles per player.	
	int size=2.5*sqrt(cNumberNonGaiaPlayers*playerTiles);
	rmEchoInfo("Map size="+size+"m x "+size+"m");
	rmSetMapSize(size, size);

	// Set up default water type.
	rmSetSeaLevel(1.0);          
	rmSetSeaType("British coast");
	rmSetBaseTerrainMix("caribbean grass");
	rmSetMapType("newEngland");
	rmSetMapType("grass");
	rmSetMapType("water");
	rmSetLightingSet("caribbean");

	// Initialize map.
	rmTerrainInitialize("water");

	// Misc variables for use later
	int numTries = -1;

	// Define some classes.
	int classPlayer=rmDefineClass("player");
	int classIsland=rmDefineClass("island");
	int classIslandSmall=rmDefineClass("islandsmall");
	int classStartingUnits = rmDefineClass("Starting Units");
	rmDefineClass("classForest");
	rmDefineClass("importantItem");
	rmDefineClass("natives");
	rmDefineClass("classSocket");
	rmDefineClass("canyon");
	rmDefineClass("classWaterTradeRoute");

  string herdableType = "ypWaterBuffalo";
  string huntable1 = "deer";
  string huntable2 = "Pheasant";
  string huntable3 = "Rabbit";
  string fish1 = "FishCod";
  string fish2 = "ypFishTuna";
  string whale1 = "HumpbackWhale";
  string startTreeType = "TreeGreatPlains";
  
   // -------------Define constraints----------------------------------------

    // Create an edge of map constraint.
	int playerEdgeConstraint=rmCreatePieConstraint("player edge of map", 0.5, 0.5, rmXFractionToMeters(0.0), rmXFractionToMeters(0.45), rmDegreesToRadians(0), rmDegreesToRadians(360));

	// Player area constraint.
	int playerConstraint=rmCreateClassDistanceConstraint("stay away from players", classPlayer, 25.0);
	int longPlayerConstraint=rmCreateClassDistanceConstraint("long stay away from players", classPlayer, 60.0);
	int flagConstraint=rmCreateHCGPConstraint("flags avoid same", 20.0);
	int nearWater10 = rmCreateTerrainDistanceConstraint("near water", "Water", true, 10.0);
	int nearWaterDock = rmCreateTerrainDistanceConstraint("near water for Dock", "Water", true, 0.0);
	int avoidTC=rmCreateTypeDistanceConstraint("stay away from TC", "TownCenter", 26.0);    //Originally 20.0 -- This adjustment, as well as changing the rmSetObjectDefMaxDistance to 12.0, has corrected the problem of nomad sometimes not placing CW for each player.
	int avoidTCfar=rmCreateTypeDistanceConstraint("stay away from TC by a lot", "TownCenter", 60.0);
	int avoidTCshort=rmCreateTypeDistanceConstraint("stay away from TC by a little bit", "TownCenter", 8.0);
	int avoidTP=rmCreateTypeDistanceConstraint("stay away from Trading Post Sockets", "SocketTradeRoute", 14.0);  // JSB 1-11-05 - Just added, to try to prevent things from stomping on TPs.
	int avoidCW=rmCreateTypeDistanceConstraint("stay away from CW", "CoveredWagon", 24.0);
	int avoidLand = rmCreateTerrainDistanceConstraint("ship avoid land", "land", true, 15.0);



	// Resource constraints - Fish, whales, forest, mines, nuggets, and sheep
	int fishVsFishID=rmCreateTypeDistanceConstraint("fish v fish", "Fish", 25.0);			// was 50.0
	// int fishVsFishTarponID=rmCreateTypeDistanceConstraint("fish v fish2", "fishTarpon", 20.0);  // was 40.0 
	int fishLand = rmCreateTerrainDistanceConstraint("fish land", "land", true, 8.0);			
	int whaleVsWhaleID=rmCreateTypeDistanceConstraint("whale v whale", "HumpbackWhale", 8.0);	//Was 8.0
	int fishVsWhaleID=rmCreateTypeDistanceConstraint("fish v whale", "HumpbackWhale", 40.0);    //Was 34.0 -- This is for trying to keep fish out of "whale bay".
	int whaleLand = rmCreateTerrainDistanceConstraint("whale land", "land", true, 17.0);   // Was 18.0.  This is to keep whales from swimming inside of land.
	int forestObjConstraint=rmCreateTypeDistanceConstraint("forest obj", "all", 6.0);
	int forestConstraint=rmCreateClassDistanceConstraint("forest vs. forest", rmClassID("classForest"), 40.0);
	int avoidResource=rmCreateTypeDistanceConstraint("resource avoid resource", "resource", 10.0);
	int avoidCoin=-1;

  int avoidHuntable1=rmCreateTypeDistanceConstraint("avoid huntable1", huntable1, 60.0);
	int avoidHuntable2=rmCreateTypeDistanceConstraint("avoid huntable2", huntable2, 60.0);
	int avoidStartResource=rmCreateTypeDistanceConstraint("start resource no overlap", "resource", 10.0);
	int avoidTradeRouteSockets=rmCreateTypeDistanceConstraint("avoid trade route sockets short", "sockettraderoute", 8.0);
	int avoidTradeRouteSocketsShort=rmCreateTypeDistanceConstraint("avoid trade route sockets short", "sockettraderoute", 8.0);
	int shortAvoidImportantItem=rmCreateClassDistanceConstraint("secrets etc avoid each other short", rmClassID("importantItem"), 8.0);
	int shortAvoidTradeRoute = rmCreateTradeRouteDistanceConstraint("trade route short", 4.0);
	int shortPlayerConstraint=rmCreateClassDistanceConstraint("short stay away from players", classPlayer, 5.0);
	
	
	// Drop coin constraint on bigger maps
	if ( cNumberNonGaiaPlayers > 5 )
	{
		avoidCoin = rmCreateTypeDistanceConstraint("avoid coin", "minegold", 75.0);
	}
	else
	{
		avoidCoin = rmCreateTypeDistanceConstraint("avoid coin", "minegold", 85.0);	// 85.0 seems the best for event minegold distribution.  This number tells minegolds how far they should try to avoid each other.  Useful for spreading them out more evenly.
	}
	int avoidRandomBerries=rmCreateTypeDistanceConstraint("avoid random berries", "berrybush", 50.0);	//Attempting to spread them out more evenly.
	int avoidRandomTurkeys=rmCreateTypeDistanceConstraint("avoid random turkeys", "turkey", 50.0);	//Attempting to spread them out more evenly.
	int avoidNugget=rmCreateTypeDistanceConstraint("nugget avoid nugget", "abstractNugget", 54.0);  //Was 60.0 -- attempting to get more nuggets in south half of isle.
	int avoidSheep=rmCreateTypeDistanceConstraint("sheep avoids sheep", "sheep", 120.0);  //Added sheep 11-28-05 JSB

	// Avoid impassable land
	int avoidImpassableLand=rmCreateTerrainDistanceConstraint("avoid impassable land", "Land", false, 5.0);
	int shortAvoidImpassableLand=rmCreateTerrainDistanceConstraint("short avoid impassable land", "Land", false, 2.0);
	int longAvoidImpassableLand=rmCreateTerrainDistanceConstraint("long avoid impassable land", "Land", false, 14.0);  //This one is used in one place: for helping place FFA TC's better.

	// Constraint to avoid water.
	int avoidWater2 = rmCreateTerrainDistanceConstraint("avoid water short", "Land", false, 2.0);   //I added this one so I could experiment with it.
	int avoidWater8 = rmCreateTerrainDistanceConstraint("avoid water long", "Land", false, 8.0);
		int avoidWater15 = rmCreateTerrainDistanceConstraint("avoid water medium 2", "Land", false, 15.0);
	int avoidWater20 = rmCreateTerrainDistanceConstraint("avoid water medium", "Land", false, 20.0);
	int avoidWater40 = rmCreateTerrainDistanceConstraint("avoid water super long", "Land", false, 40.0);  //Added this one too.
	int flagLand = rmCreateTerrainDistanceConstraint("flag vs land", "land", true, 18.0);
	int flagVsFlag = rmCreateTypeDistanceConstraint("flag avoid same", "HomeCityWaterSpawnFlag", 25); //Was 15, but made larger so ships don't sometimes stomp each other when arriving from HC.
	rmAddClosestPointConstraint(avoidWater8);  //was originally 8
	int avoidTradeRoute = rmCreateTradeRouteDistanceConstraint("trade route", 6.0);
	int avoidWaterTradeRoute = rmCreateClassDistanceConstraint("avoid water socket", rmClassID("classWaterTradeRoute"), 10.0);
	int avoidSocket = rmCreateClassDistanceConstraint("avoid socket", rmClassID("classSocket"), 10.0);
	int avoidImportantItem = rmCreateClassDistanceConstraint("secrets etc avoid each other", rmClassID("importantItem"), 50.0);
	int avoidAll=rmCreateTypeDistanceConstraint("avoid all", "all", 4.0);

	// The following is a Pie constraint, defined in a large "majority of the pie plate" area, to make sure Water spawn flags place inside it.  (It excludes the west bay, where I do not want the flags.)
	int circleConstraint=rmCreatePieConstraint("semi-circle Constraint", 0.5, 0.5, 0, rmZFractionToMeters(0.47), rmDegreesToRadians(50), rmDegreesToRadians(290));  //rmZFractionToMeters(0.47)- this number defines how far out from .5, .5 the center of the pie sections go. 

  int flagEdgeConstraint = rmCreatePieConstraint("flags away from edge of map", 0.5, 0.5, rmGetMapXSize()-200, rmGetMapXSize()-100, 0, 0, 0);
	
	// --------------- Make load bar move. ----------------------------------------------------------------------------
	rmSetStatusText("",0.30);

	int avoidNatives=rmCreateClassDistanceConstraint("stuff avoids natives", rmClassID("natives"), 50.0);
	int avoidNativesShort=rmCreateClassDistanceConstraint("stuff avoids natives by a bit", rmClassID("natives"), 20.0);



/////////////////////////////// ISLANDS ////////////////////////////////////

	// Bonus area constraint.  
	int islandConstraint=rmCreateClassDistanceConstraint("islands avoid each other", classIsland, 30.0);
	int islandConstraint2=rmCreateClassDistanceConstraint("islands avoid each other 2", classIsland, 10.0);
	int islandConstraintSmall=rmCreateClassDistanceConstraint("islands avoid each other 3", classIslandSmall, 10.0);

   int IslandLoc = 1;								

	// Make BRITAIN

	int BritainID=rmCreateArea("Island 1");
	rmSetAreaSize(BritainID, 0.12, 0.12);				//Defines island's size.  .40, .40 looks about right.
	rmSetAreaCoherence(BritainID, 0.35);				//Determines raggedness of island's coastline.  Lower the number, more the blobby.
	rmSetAreaBaseHeight(BritainID, 2.0);
	rmSetAreaSmoothDistance(BritainID, 10);
	rmSetAreaMix(BritainID, "newengland_grass");
	rmAddAreaToClass(BritainID, classIsland);
	rmAddAreaConstraint(BritainID, islandConstraint);
	rmAddAreaConstraint(BritainID, islandConstraintSmall);
	rmAddAreaConstraint(BritainID, avoidTradeRoute);
	rmSetAreaObeyWorldCircleConstraint(BritainID, false);
	rmSetAreaElevationType(BritainID, cElevTurbulence);
	rmSetAreaElevationVariation(BritainID, 4.0);
	rmSetAreaElevationMinFrequency(BritainID, 0.09);
	rmSetAreaElevationOctaves(BritainID, 3);
	rmSetAreaElevationPersistence(BritainID, 0.2);
	rmSetAreaElevationNoiseBias(BritainID, 1);
	rmAddAreaInfluenceSegment(BritainID, 0.52, 0.25, 0.7, 0.61);  

	// Make IRELAND

	int IrelandID=rmCreateArea("Island 2");
	rmSetAreaSize(IrelandID, 0.05, 0.05);				//Defines island's size.  .40, .40 looks about right.
	rmSetAreaCoherence(IrelandID, 0.30);				//Determines raggedness of island's coastline.  Lower the number, more the blobby.
	rmSetAreaBaseHeight(IrelandID, 2.0);
	rmSetAreaSmoothDistance(IrelandID, 10);
	rmSetAreaMix(IrelandID, "newengland_grass");
	rmAddAreaToClass(IrelandID, classIsland);
	rmAddAreaConstraint(IrelandID, islandConstraint);
	rmAddAreaConstraint(IrelandID, islandConstraintSmall);
	rmAddAreaConstraint(IrelandID, avoidTradeRoute);
	rmSetAreaObeyWorldCircleConstraint(IrelandID, false);
	rmSetAreaElevationType(IrelandID, cElevTurbulence);
	rmSetAreaElevationVariation(IrelandID, 4.0);
	rmSetAreaElevationMinFrequency(IrelandID, 0.09);
	rmSetAreaElevationOctaves(IrelandID, 3);
	rmSetAreaElevationPersistence(IrelandID, 0.2);
	rmSetAreaElevationNoiseBias(IrelandID, 1);


	// Make ISLE OF MAN

	int IsleofmanID=rmCreateArea("Isle of Man");
	rmSetAreaSize(IsleofmanID, 0.005, 0.005);				//Defines island's size.  .40, .40 looks about right.
	rmSetAreaCoherence(IsleofmanID, 0.30);				//Determines raggedness of island's coastline.  Lower the number, more the blobby.
	rmSetAreaBaseHeight(IsleofmanID, 2.0);
	rmSetAreaSmoothDistance(IsleofmanID, 10);
	rmSetAreaMix(IsleofmanID, "newengland_grass");
	rmAddAreaToClass(IsleofmanID, classIslandSmall);
	rmAddAreaConstraint(IsleofmanID, islandConstraint2);
	rmAddAreaConstraint(IsleofmanID, avoidTradeRoute);
	rmSetAreaObeyWorldCircleConstraint(IsleofmanID, false);
	rmSetAreaElevationType(IsleofmanID, cElevTurbulence);
	rmSetAreaElevationVariation(IsleofmanID, 4.0);
	rmSetAreaElevationMinFrequency(IsleofmanID, 0.09);
	rmSetAreaElevationOctaves(IsleofmanID, 3);
	rmSetAreaElevationPersistence(IsleofmanID, 0.2);
	rmSetAreaElevationNoiseBias(IsleofmanID, 1);

	// Make HEBRIDES

	int HebridesID=rmCreateArea("Hebrides");
	rmSetAreaSize(HebridesID, 0.005, 0.005);				//Defines island's size.  .40, .40 looks about right.
	rmSetAreaCoherence(HebridesID, 0.30);				//Determines raggedness of island's coastline.  Lower the number, more the blobby.
	rmSetAreaBaseHeight(HebridesID, 2.0);
	rmSetAreaSmoothDistance(HebridesID, 10);
	rmSetAreaMix(HebridesID, "newengland_grass");
	rmAddAreaToClass(HebridesID, classIslandSmall);
	rmAddAreaConstraint(HebridesID, islandConstraint2);
	rmAddAreaConstraint(HebridesID, avoidTradeRoute);
	rmSetAreaObeyWorldCircleConstraint(HebridesID, false);
	rmSetAreaElevationType(HebridesID, cElevTurbulence);
	rmSetAreaElevationVariation(HebridesID, 4.0);
	rmSetAreaElevationMinFrequency(HebridesID, 0.09);
	rmSetAreaElevationOctaves(HebridesID, 3);
	rmSetAreaElevationPersistence(HebridesID, 0.2);
	rmSetAreaElevationNoiseBias(HebridesID, 1);

	rmSetAreaWarnFailure(BritainID, false);
	rmSetAreaWarnFailure(IrelandID, false);
	rmSetAreaWarnFailure(IsleofmanID, false);
	rmSetAreaWarnFailure(HebridesID, false);




	if (IslandLoc == 1)

	rmSetAreaLocation(IsleofmanID, .51, .51);		
	rmBuildArea(IsleofmanID);

	rmSetAreaLocation(HebridesID, .65, .81);		
	rmBuildArea(HebridesID);

	rmSetAreaLocation(BritainID, .6, .45);		
	rmBuildArea(BritainID);

	rmSetAreaLocation(IrelandID, .32, .58);		
	rmBuildArea(IrelandID);
 

/////////////////////////////// PLACE LAND TRADE ROUTE ////////////////////////////////////


   int socketID=rmCreateObjectDef("sockets to dock Trade Posts");
	rmAddObjectDefItem(socketID, "SocketTradeRoute", 1, 0.0);
	rmSetObjectDefAllowOverlap(socketID, true);
	rmSetObjectDefMinDistance(socketID, 0.0);
	rmSetObjectDefMaxDistance(socketID, 6.0);


	int tradeRouteID = rmCreateTradeRoute();

	rmSetObjectDefTradeRouteID(socketID, tradeRouteID);
	rmAddTradeRouteWaypoint(tradeRouteID, .46, .22);	
	rmAddTradeRouteWaypoint(tradeRouteID, .55, .19);
	rmAddTradeRouteWaypoint(tradeRouteID, .69, .41);
	rmAddTradeRouteWaypoint(tradeRouteID, .77, .61);	
	rmAddTradeRouteWaypoint(tradeRouteID, .7, .68);
	rmAddTradeRouteWaypoint(tradeRouteID, .61, .66);
	rmAddTradeRouteWaypoint(tradeRouteID, .61, .56);
	rmAddTradeRouteWaypoint(tradeRouteID, .6, .43);
	rmAddTradeRouteWaypoint(tradeRouteID, .48, .31);
	rmAddTradeRouteWaypoint(tradeRouteID, .46, .22);

	bool placedTradeRouteA = rmBuildTradeRoute(tradeRouteID, "TrainBritishIsles1");
	if(placedTradeRouteA == false)
		rmEchoError("Failed to place trade route 1");

		rmPlaceObjectDefAtLoc(socketID, 0, .61, .56); // -2
		rmPlaceObjectDefAtLoc(socketID, 0, .48, .31); // -4
		rmPlaceObjectDefAtLoc(socketID, 0, .77, .61); // -4

// IRISH ONE

   int socketID2=rmCreateObjectDef("sockets to dock Trade Posts2");
	rmAddObjectDefItem(socketID2, "SocketTradeRoute", 1, 0.0);
	rmSetObjectDefAllowOverlap(socketID2, true);
	rmSetObjectDefMinDistance(socketID2, 0.0);
	rmSetObjectDefMaxDistance(socketID2, 6.0);


	int tradeRouteID2 = rmCreateTradeRoute();

	rmSetObjectDefTradeRouteID(socketID2, tradeRouteID2);
	rmAddTradeRouteWaypoint(tradeRouteID2, .29, .49);	
	rmAddTradeRouteWaypoint(tradeRouteID2, .31, .49);	
	rmAddTradeRouteWaypoint(tradeRouteID2, .39, .57);
	rmAddTradeRouteWaypoint(tradeRouteID2, .36, .65);
	rmAddTradeRouteWaypoint(tradeRouteID2, .27, .66);	
	rmAddTradeRouteWaypoint(tradeRouteID2, .23, .58);
	rmAddTradeRouteWaypoint(tradeRouteID2, .29, .49);

	bool placedTradeRouteB = rmBuildTradeRoute(tradeRouteID2, "TrainBritishIsles1");
	if(placedTradeRouteB == false)
		rmEchoError("Failed to place trade route 2");

		rmPlaceObjectDefAtLoc(socketID2, 0, .31, .49); // -2
		rmPlaceObjectDefAtLoc(socketID2, 0, .27, .66); // -2



/////////////////////////////// PLACE PLAYERS ////////////////////////////////////


	int startingUnits = rmCreateStartingUnitsObjectDef(5.0);
	int verylongPlayerConstraint=rmCreateClassDistanceConstraint("very long stay away from players", classPlayer, 60.0);
	   int avoidStartingUnits = rmCreateClassDistanceConstraint("Avoid starting units", classStartingUnits, 10.0);
	   
	int TCfloat = -1;
  if (cNumberTeams == 2)
	   TCfloat = 110;
  else 
	   TCfloat = 220;

	int TCID = rmCreateObjectDef("player TC");
	if ( rmGetNomadStart())
		rmAddObjectDefItem(TCID, "coveredWagon", 1, 0);
	else
		rmAddObjectDefItem(TCID, "townCenter", 1, 0);
    
	rmSetObjectDefMinDistance(TCID, 0.0);
	rmSetObjectDefMaxDistance(TCID, TCfloat);
	rmAddObjectDefToClass(TCID, classPlayer);
	rmAddObjectDefConstraint(TCID, avoidImpassableLand);
	rmAddObjectDefConstraint(TCID, verylongPlayerConstraint);
	rmAddObjectDefConstraint(TCID, avoidWater15);
	rmAddObjectDefConstraint(TCID, playerEdgeConstraint);
	rmAddObjectDefConstraint(TCID, avoidNatives);
	rmAddObjectDefConstraint(TCID, shortAvoidTradeRoute);
	
	int playerSilverID = rmCreateObjectDef("player silver");
	rmAddObjectDefItem(playerSilverID, "minecoal", 1, 0);
	rmAddObjectDefConstraint(playerSilverID, avoidTradeRoute);
	rmSetObjectDefMinDistance(playerSilverID, 10.0);
	rmSetObjectDefMaxDistance(playerSilverID, 30.0);
	rmAddObjectDefConstraint(playerSilverID, avoidAll);
  rmAddObjectDefConstraint(playerSilverID, avoidImpassableLand);
    rmAddObjectDefConstraint(playerSilverID, avoidStartingUnits);

	int playersalamanderID=rmCreateObjectDef("player deer");
  rmAddObjectDefItem(playersalamanderID, huntable3, rmRandInt(5,8), 10.0);
  rmSetObjectDefMinDistance(playersalamanderID, 15.0);
  rmSetObjectDefMaxDistance(playersalamanderID, 30.0);
	rmAddObjectDefConstraint(playersalamanderID, avoidAll);
  rmAddObjectDefConstraint(playersalamanderID, avoidImpassableLand);
  rmSetObjectDefCreateHerd(playersalamanderID, true);
  	rmAddObjectDefConstraint(playersalamanderID, shortAvoidTradeRoute);
	    rmAddObjectDefConstraint(playersalamanderID, avoidStartingUnits);
 
  int StartAreaTreeID=rmCreateObjectDef("starting trees");
	rmAddObjectDefItem(StartAreaTreeID, startTreeType, 6, 6.0);
	rmSetObjectDefMinDistance(StartAreaTreeID, 16);
	rmSetObjectDefMaxDistance(StartAreaTreeID, 22);
	rmAddObjectDefConstraint(StartAreaTreeID, avoidAll);
	rmAddObjectDefConstraint(StartAreaTreeID, avoidStartResource);
	rmAddObjectDefConstraint(StartAreaTreeID, shortAvoidImpassableLand);
  rmAddObjectDefConstraint(StartAreaTreeID, avoidTradeRouteSocketsShort);
  rmAddObjectDefConstraint(StartAreaTreeID, shortAvoidTradeRoute);
  	    rmAddObjectDefConstraint(StartAreaTreeID, avoidStartingUnits);


	int StartBerriesID=rmCreateObjectDef("starting berries");
	rmAddObjectDefItem(StartBerriesID, "berrybush", 4, 5.0);
	rmSetObjectDefMinDistance(StartBerriesID, 10);
	rmSetObjectDefMaxDistance(StartBerriesID, 15);
	rmAddObjectDefConstraint(StartBerriesID, avoidAll);
	rmAddObjectDefConstraint(StartBerriesID, avoidStartResource);
	rmAddObjectDefConstraint(StartBerriesID, shortAvoidImpassableLand);
	rmAddObjectDefConstraint(StartBerriesID, shortPlayerConstraint);
  rmAddObjectDefConstraint(StartBerriesID, shortAvoidTradeRoute);
    	    rmAddObjectDefConstraint(StartBerriesID, avoidStartingUnits);
			
			
	  int food1ID=rmCreateObjectDef("huntable1");
	rmAddObjectDefItem(food1ID, huntable1, rmRandInt(6,8), 6.0);
	rmSetObjectDefCreateHerd(food1ID, true);
	rmSetObjectDefMinDistance(food1ID, 0.0);
	rmSetObjectDefMaxDistance(food1ID, rmXFractionToMeters(0.45));
	rmAddObjectDefConstraint(food1ID, avoidResource);
	rmAddObjectDefConstraint(food1ID, playerConstraint);
	rmAddObjectDefConstraint(food1ID, avoidImpassableLand);
	rmAddObjectDefConstraint(food1ID, avoidHuntable1);
	rmAddObjectDefConstraint(food1ID, avoidHuntable2);
  rmAddObjectDefConstraint(food1ID, shortAvoidImportantItem);
	rmAddObjectDefConstraint(food1ID, avoidTradeRouteSocketsShort);
		  rmAddObjectDefConstraint(food1ID, shortAvoidTradeRoute);
  
  int food2ID=rmCreateObjectDef("huntable2");
	rmAddObjectDefItem(food2ID, huntable2, rmRandInt(6,8), 6.0);
	rmSetObjectDefCreateHerd(food2ID, true);
	rmSetObjectDefMinDistance(food2ID, 0.0);
	rmSetObjectDefMaxDistance(food2ID, rmXFractionToMeters(0.45));
	rmAddObjectDefConstraint(food2ID, avoidResource);
	rmAddObjectDefConstraint(food2ID, longPlayerConstraint);
	rmAddObjectDefConstraint(food2ID, avoidImpassableLand);
	rmAddObjectDefConstraint(food2ID, avoidHuntable1);
	rmAddObjectDefConstraint(food2ID, avoidHuntable2);
	rmAddObjectDefConstraint(food2ID, shortAvoidImportantItem);
	rmAddObjectDefConstraint(food2ID, avoidTradeRouteSocketsShort);
	  rmAddObjectDefConstraint(food2ID, shortAvoidTradeRoute);
	
	
	  int playerNuggetID=rmCreateObjectDef("player nugget");
  rmAddObjectDefItem(playerNuggetID, "nugget", 1, 0.0);
  rmSetObjectDefMinDistance(playerNuggetID, 15.0);
  rmSetObjectDefMaxDistance(playerNuggetID, 20.0);
	rmAddObjectDefConstraint(playerNuggetID, avoidAll);
	rmAddObjectDefConstraint(playerNuggetID, avoidImpassableLand);
  rmAddObjectDefConstraint(playerNuggetID, avoidTradeRoute);
  
  
      /////////////////////////////// PLACE CITIES ////////////////////////////////////
	  

         int cityType = rmRandInt(1,3);
         int cityID = 0;
         cityID = rmCreateGrouping("British City", "british city "+cityType);
         rmSetGroupingMinDistance(cityID, 5.0);
         rmSetGroupingMaxDistance(cityID, 20.0);
         rmAddGroupingToClass(cityID, avoidAll);
		       rmAddGroupingToClass(cityID, classStartingUnits);
         rmAddGroupingConstraint(cityID, avoidStartResource);
		 rmAddGroupingConstraint(cityID, shortAvoidTradeRoute);
		rmAddGroupingConstraint(cityID, shortAvoidImpassableLand);
  

/////////////////////////////// PLACE PLAYERS ////////////////////////////////////

  // starting resources

    // Text
   rmSetStatusText("",0.35);
  
  rmClearClosestPointConstraints();

	for(i=1; < cNumberPlayers) {
	//	int placedTC = rmPlaceObjectDefAtLoc(TCID, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));
	
	int fail=0;
	
	int IslandChooser = rmRandInt(1,4);
	int ChosenIsland = -1;
		if (IslandChooser < 2)
		{
			ChosenIsland = IrelandID;
		}
		else
		{
            ChosenIsland = BritainID;
		}
		
    fail=0;
    for(j=2; >fail*1000) // Make sure the TC gets added somewhere
	
	{fail=rmPlaceObjectDefInArea(TCID, i, ChosenIsland, 1);}
	
		vector TCLocation=rmGetUnitPosition(rmGetUnitPlacedOfPlayer(TCID, i));
		rmPlaceObjectDefAtLoc(startingUnits, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
		        rmPlaceGroupingAtLoc(cityID, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
		rmPlaceObjectDefAtLoc(playerSilverID, 0, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
		rmPlaceObjectDefAtLoc(StartAreaTreeID, 0, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));

			
   // Food
	rmPlaceObjectDefAtLoc(StartBerriesID, 0, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
    rmPlaceObjectDefAtLoc(playersalamanderID, 0, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
	

	   
    // Place a nugget for the player
    rmSetNuggetDifficulty(1, 1);
    rmPlaceObjectDefAtLoc(playerNuggetID, 0, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
 


		
    // Place water spawn points for the players
		int waterSpawnPointID=rmCreateObjectDef("colony ship "+i);
		rmAddObjectDefItem(waterSpawnPointID, "HomeCityWaterSpawnFlag", 1, 10.0);
		rmAddClosestPointConstraint(flagVsFlag);
		rmAddClosestPointConstraint(flagLand);
    rmAddClosestPointConstraint(flagEdgeConstraint);
		vector closestPoint = rmFindClosestPointVector(TCLocation, rmXFractionToMeters(1.0));
		rmPlaceObjectDefAtLoc(waterSpawnPointID, i, rmXMetersToFraction(xsVectorGetX(closestPoint)), rmZMetersToFraction(xsVectorGetZ(closestPoint)));

    rmClearClosestPointConstraints();
  }


  
  /////////////////////////////// MINES ////////////////////////////////////

	int avoidSilver=rmCreateTypeDistanceConstraint("avoid coal mines", "minecoal", 75.0);
	
	// Silver

	int silverID = -1;
 	int silverID2 = -1;

  int silverCount = 0;
  
  silverCount = cNumberNonGaiaPlayers*2;
  
	rmEchoInfo("silver count = "+silverCount);


  // silver mines over the entirety of the island
  silverID2 = rmCreateObjectDef("closer silver mines"+i);
  rmAddObjectDefItem(silverID2, "minecoal", 1, 0.0);
  rmSetObjectDefMinDistance(silverID2, rmXFractionToMeters(0.0));
  rmSetObjectDefMaxDistance(silverID2, rmXFractionToMeters(0.5));
  rmAddObjectDefConstraint(silverID2, avoidImpassableLand);
  rmAddObjectDefConstraint(silverID2, avoidSilver);
  rmAddObjectDefConstraint(silverID2, longPlayerConstraint);
  rmAddObjectDefConstraint(silverID2, shortAvoidTradeRoute);
  rmAddObjectDefConstraint(silverID2, shortAvoidImportantItem);
  rmAddObjectDefConstraint(silverID2, avoidTradeRouteSocketsShort);
  rmPlaceObjectDefAtLoc(silverID2, 0, 0.5, 0.5, silverCount);
  
  
  /////////////////////////////// TREASURES ////////////////////////////////////

  int playerConstraintNugget=rmCreateClassDistanceConstraint("stay away from players far", classPlayer, 55.0);
  int avoidNuggetsShort=rmCreateTypeDistanceConstraint("vs nugget short", "AbstractNugget", 10.0);
    int avoidNuggets=rmCreateTypeDistanceConstraint("nugget vs. nugget", "AbstractNugget", 40.0);
	int avoidNuggetFar=rmCreateTypeDistanceConstraint("nugget vs. nugget far", "AbstractNugget", 70.0);
	
  int nugget4= rmCreateObjectDef("nugget nuts"); 
  rmAddObjectDefItem(nugget4, "Nugget", 1, 0.0);
  rmSetNuggetDifficulty(4, 4);
  rmSetObjectDefMinDistance(nugget4, 0.0);
  rmSetObjectDefMaxDistance(nugget4, rmXFractionToMeters(0.2));
  rmAddObjectDefConstraint(nugget4, avoidImpassableLand);
  rmAddObjectDefConstraint(nugget4, shortAvoidImportantItem);
  rmAddObjectDefConstraint(nugget4, avoidResource);
  rmAddObjectDefConstraint(nugget4, avoidNuggets);
  rmAddObjectDefConstraint(nugget4, shortAvoidTradeRoute);
  rmAddObjectDefConstraint(nugget4, avoidTradeRouteSockets);
  rmAddObjectDefConstraint(nugget4, playerConstraintNugget);
  rmAddObjectDefConstraint(nugget4, circleConstraint);
  rmPlaceObjectDefAtLoc(nugget4, 0, 0.5, 0.5, cNumberNonGaiaPlayers);

  int nugget3= rmCreateObjectDef("nugget hard"); 
  rmAddObjectDefItem(nugget3, "Nugget", 1, 0.0);
  rmSetNuggetDifficulty(3, 3);
  rmSetObjectDefMinDistance(nugget3, 0.0);
  rmSetObjectDefMaxDistance(nugget3, rmXFractionToMeters(0.2));
  rmAddObjectDefConstraint(nugget3, avoidImpassableLand);
  rmAddObjectDefConstraint(nugget3, shortAvoidImportantItem);
  rmAddObjectDefConstraint(nugget3, avoidResource);
  rmAddObjectDefConstraint(nugget3, avoidNuggets);
  rmAddObjectDefConstraint(nugget3, shortAvoidTradeRoute);
  rmAddObjectDefConstraint(nugget3, avoidTradeRouteSockets);
  rmAddObjectDefConstraint(nugget3, playerConstraintNugget);
  rmAddObjectDefConstraint(nugget3, circleConstraint);
  rmPlaceObjectDefAtLoc(nugget3, 0, 0.5, 0.5, cNumberNonGaiaPlayers+rmRandInt(1,1));

  int nugget2= rmCreateObjectDef("nugget medium"); 
  rmAddObjectDefItem(nugget2, "Nugget", 1, 0.0);
  rmSetNuggetDifficulty(2, 2);
  rmAddObjectDefConstraint(nugget2, avoidImpassableLand);
  rmAddObjectDefConstraint(nugget2, shortAvoidImportantItem);
  rmAddObjectDefConstraint(nugget2, avoidResource);
  rmAddObjectDefConstraint(nugget2, avoidNuggetFar);
  rmAddObjectDefConstraint(nugget2, shortAvoidTradeRoute);
  rmAddObjectDefConstraint(nugget2, avoidTradeRouteSockets);
  rmAddObjectDefConstraint(nugget2, playerConstraintNugget);
  rmAddObjectDefConstraint(nugget2, circleConstraint);
  rmSetObjectDefMinDistance(nugget2, rmXFractionToMeters(0.25));
  rmSetObjectDefMaxDistance(nugget2, rmXFractionToMeters(0.3));
  rmPlaceObjectDefAtLoc(nugget2, 0, 0.5, 0.5, 2*cNumberNonGaiaPlayers);

  int nugget1= rmCreateObjectDef("nugget easy"); 
  rmAddObjectDefItem(nugget1, "Nugget", 1, 0.0);
  rmSetNuggetDifficulty(1, 1);
  rmAddObjectDefConstraint(nugget1, avoidImpassableLand);
  rmAddObjectDefConstraint(nugget1, shortAvoidImportantItem);
  rmAddObjectDefConstraint(nugget1, avoidNuggetFar);
  rmAddObjectDefConstraint(nugget1, shortAvoidTradeRoute);
  rmAddObjectDefConstraint(nugget1, avoidTradeRouteSockets);
  rmAddObjectDefConstraint(nugget1, playerConstraint);
  rmAddObjectDefConstraint(nugget1, circleConstraint);
  rmSetObjectDefMinDistance(nugget1, rmXFractionToMeters(0.3));
  rmSetObjectDefMaxDistance(nugget1, rmXFractionToMeters(0.4));
  rmPlaceObjectDefAtLoc(nugget1, 0, 0.5, 0.5, 3*cNumberNonGaiaPlayers);
  
  
  /////////////////////////////// FORESTS ////////////////////////////////////

	// Scattered FORESTS
   int forestTreeID = 0;
   numTries=10*cNumberNonGaiaPlayers;
   int failCount=0;
   for (i=0; <numTries)
      {   
         int forest=rmCreateArea("forest "+i);
         rmSetAreaWarnFailure(forest, false);
         rmSetAreaSize(forest, rmAreaTilesToFraction(150), rmAreaTilesToFraction(400));
         rmSetAreaForestType(forest, "Great Plains forest");
         rmSetAreaForestDensity(forest, 0.6);
         rmSetAreaForestClumpiness(forest, 0.4);
         rmSetAreaForestUnderbrush(forest, 0.0);
         rmSetAreaMinBlobs(forest, 1);
         rmSetAreaMaxBlobs(forest, 5);
         rmSetAreaMinBlobDistance(forest, 16.0);
         rmSetAreaMaxBlobDistance(forest, 40.0);
         rmSetAreaCoherence(forest, 0.4);
         rmSetAreaSmoothDistance(forest, 10);
         rmAddAreaToClass(forest, rmClassID("classForest")); 
         rmAddAreaConstraint(forest, forestConstraint);
         rmAddAreaConstraint(forest, avoidAll);
         rmAddAreaConstraint(forest, shortAvoidImpassableLand); 
		 rmAddAreaConstraint(forest, avoidTC);
		 rmAddAreaConstraint(forest, avoidCW);
         rmAddAreaConstraint(forest, avoidTradeRoute); 
         if(rmBuildArea(forest)==false)
         {
            // Stop trying once we fail 3 times in a row.
            failCount++;
            if(failCount==5)
               break;
         }
         else
            failCount=0; 
      } 
	  
	  /////////////////////////////// HUNTABLES ////////////////////////////////////

  rmPlaceObjectDefAtLoc(food1ID, 0, 0.5, 0.5, 2.5*cNumberNonGaiaPlayers);
  rmPlaceObjectDefAtLoc(food2ID, 0, 0.5, 0.5, 3.0*cNumberNonGaiaPlayers);
  
	  
  /////////////////////////////// FISH ////////////////////////////////////


	int fishVsFish2ID=rmCreateTypeDistanceConstraint("fish v fish2", fish2, 15.0); 
  int whaleEdgeConstraint=rmCreatePieConstraint("whale edge of map", 0.5, 0.5, 0, rmGetMapXSize()-25, 0, 0, 0);

  int fishID=rmCreateObjectDef("fish 1");
  rmAddObjectDefItem(fishID, fish1, 1, 0.0);
  rmSetObjectDefMinDistance(fishID, 0.0);
  rmSetObjectDefMaxDistance(fishID, rmXFractionToMeters(0.5));
  rmAddObjectDefConstraint(fishID, fishVsFishID);
  rmAddObjectDefConstraint(fishID, fishLand);
  rmPlaceObjectDefAtLoc(fishID, 0, 0.5, 0.5, 7*cNumberNonGaiaPlayers);
    
  int fish2ID=rmCreateObjectDef("fish 2");
  rmAddObjectDefItem(fish2ID, fish2, 1, 0.0);
  rmSetObjectDefMinDistance(fish2ID, 0.0);
  rmSetObjectDefMaxDistance(fish2ID, rmXFractionToMeters(0.5));
  rmAddObjectDefConstraint(fish2ID, fishVsFish2ID);
  rmAddObjectDefConstraint(fish2ID, fishLand);
  rmPlaceObjectDefAtLoc(fish2ID, 0, 0.5, 0.5, 6*cNumberNonGaiaPlayers);
  
  // extra fish for under 5 players
  if (cNumberNonGaiaPlayers < 5) {
    int fish3ID=rmCreateObjectDef("fish 3");
    rmAddObjectDefItem(fish3ID, fish1, 1, 0.0);
    rmSetObjectDefMinDistance(fish3ID, 0.0);
    rmSetObjectDefMaxDistance(fish3ID, rmXFractionToMeters(0.5));
    rmAddObjectDefConstraint(fish3ID, fishVsFishID);
    rmAddObjectDefConstraint(fish3ID, fishLand);
    rmPlaceObjectDefAtLoc(fish3ID, 0, 0.5, 0.5, 6*cNumberNonGaiaPlayers);
  }  
    
  int whaleID=rmCreateObjectDef("whale");
  rmAddObjectDefItem(whaleID, whale1, 1, 0.0);
  rmSetObjectDefMinDistance(whaleID, 0.0);
  rmSetObjectDefMaxDistance(whaleID, rmXFractionToMeters(0.5));
  rmAddObjectDefConstraint(whaleID, whaleVsWhaleID);  
  rmAddObjectDefConstraint(whaleID, whaleEdgeConstraint);
  rmAddObjectDefConstraint(whaleID, whaleLand);
  rmPlaceObjectDefAtLoc(whaleID, 0, 0.5, 0.5, 4*cNumberNonGaiaPlayers);


    /////////////////////////////// RAIN ////////////////////////////////////
	
	
	// Make it rain
	rmSetGlobalRain( 1.0 );
	rmSetGlobalStormLength(1.0, 0.0);

	// Sets up the rain triggers - rain hard for 20 seconds, then lightly, then hard again, then medium, then off.
	rmCreateTrigger("ChangeRain1");
	rmSwitchToTrigger(rmTriggerID("ChangeRain1"));
	rmSetTriggerActive(true);
	rmAddTriggerCondition("Timer");
	rmSetTriggerConditionParamInt("Param1", 20);
	rmAddTriggerEffect("Render Rain");
	rmSetTriggerEffectParamFloat("Percent", 0.3);

	rmCreateTrigger("ChangeRain2");
	rmSwitchToTrigger(rmTriggerID("ChangeRain2"));
	rmSetTriggerActive(true);
	rmAddTriggerCondition("Timer");
	rmSetTriggerConditionParamInt("Param1", 40);
	rmAddTriggerEffect("Render Rain");
	rmSetTriggerEffectParamFloat("Percent", 1.0);

	rmCreateTrigger("ChangeRain3");
	rmSwitchToTrigger(rmTriggerID("ChangeRain3"));
	rmSetTriggerActive(true);
	rmAddTriggerCondition("Timer");
	rmSetTriggerConditionParamInt("Param1", 60);
	rmAddTriggerEffect("Render Rain");
	rmSetTriggerEffectParamFloat("Percent", 0.3);

	rmCreateTrigger("ChangeRain4");
	rmSwitchToTrigger(rmTriggerID("ChangeRain4"));
	rmSetTriggerActive(true);
	rmAddTriggerCondition("Timer");
	rmSetTriggerConditionParamInt("Param1", 75);
	rmAddTriggerEffect("Render Rain");
	rmSetTriggerEffectParamFloat("Percent", 0.0);
	
	
  }
  
  